﻿using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Sinacor.Infra.Service.Data;
using Sinacor.Infra.Service.Security;
using System.Data.Common;
using System.Data;
using Sinacor.Servico.Bovespa.BovespaBase.Util;
using System.Transactions;
using Sinacor.Infra.Service.Security.Authorization;

namespace Sinacor.Servico.Bovespa.Ordens.ResourceAccess
{
	public class PreBoleto : BaseResourceAccess
    {
        public PreBoleto()
            : base(AuthorizationContext.Current.CompanyId) 
        {
        
        }
        //20080512 19:43 - RValadao
        //Criado constantes para os erros
        #region Costantes de erros
        private int ERRO_EXISTE_PRIORIDADE_MAIOR = 103201;
        private int ERRO_EXISTE_CONCORRENCIA = 103202;
        #endregion
        /// <summary>
		/// Metodo responsavel por incluir um preboleto
		/// Historico:
		/// Data: 26/11/2007
		/// Autor: Diogo Milanez
		/// Observacoes: 
		/// * criacao do metodo
		/// * retorno foi alterado para void
		/// </summary>
		/// <param name="preBoleto"></param>
		/// <returns></returns>
		public void Incluir( Bovespa.Ordens.BusinessEntity.PreBoleto preBoleto)
		{
			int sequencial=0;
			StringBuilder sql = new StringBuilder();
			
			///recuperar o sequencial da tabela de sequenciais
			sql.AppendLine("SELECT NR_SEQDET FROM TORSEQDET FOR UPDATE");			
			DbCommand dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());
			sequencial = Convert.ToInt32(this.DataBase.ExecuteScalar(dbCommand)) + 1;

			///atualizar o sequencial armazenado na tabela
			sql = new StringBuilder();
			sql.AppendLine("UPDATE TORSEQDET SET NR_SEQDET= :Sequencial");
			dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());
			this.DataBase.AddInParameter(dbCommand, "Sequencial",DbType.Int32, sequencial);			
			this.DataBase.ExecuteNonQuery(dbCommand);
		
			sql = new StringBuilder();
			sql.AppendLine("INSERT INTO TORDETD (");
			sql.AppendLine("NR_SEQDET,");
			sql.AppendLine("IN_SITUAC,");
			sql.AppendLine("DT_DATORD,");
			sql.AppendLine("NR_SEQORD,");
			sql.AppendLine("NR_SUBSEQ,");
			sql.AppendLine("DT_HORORD,");
			sql.AppendLine("DT_DATMOV,");
			sql.AppendLine("TP_ORDEM,");
			sql.AppendLine("CD_MERCAD,");
			sql.AppendLine("QT_ORDEM,");
			sql.AppendLine("VL_PREPAP,");
			sql.AppendLine("CD_CONTRAPARTE,");
			sql.AppendLine("IN_TOTAL,");
			sql.AppendLine("TP_ESTRATEGIA,");
			sql.AppendLine("VL_DOLAR,");
			sql.AppendLine("NR_OFEMEGA )");
			sql.AppendLine("VALUES (");
			sql.AppendLine(":NR_SEQDET,");
			sql.AppendLine(":IN_SITUAC,");
			sql.AppendLine(":DT_DATORD,");
			sql.AppendLine(":NR_SEQORD,");
			sql.AppendLine(":NR_SUBSEQ,");
			sql.AppendLine(":DT_HORORD,");
			sql.AppendLine(":DT_DATMOV,");
			sql.AppendLine(":TP_ORDEM,");
			sql.AppendLine(":CD_MERCAD,");
			sql.AppendLine(":QT_ORDEM,");
			sql.AppendLine(":VL_PREPAP,");
			sql.AppendLine(":CD_CONTRAPARTE,");
			sql.AppendLine(":IN_TOTAL,");
			sql.AppendLine(":TP_ESTRATEGIA,");
			sql.AppendLine(":VL_DOLAR,");
			sql.AppendLine(":NR_OFEMEGA )");

			dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());

			this.DataBase.AddInParameter(dbCommand, "NR_SEQDET", DbType.Int32, sequencial);
			this.DataBase.AddInParameter(dbCommand, "IN_SITUAC", DbType.AnsiString, preBoleto.Ordem.Situacao);
			this.DataBase.AddInParameter(dbCommand, "DT_DATORD", DbType.Date, preBoleto.Ordem.DataOrdem.Value);
			this.DataBase.AddInParameter(dbCommand, "NR_SEQORD", DbType.Int32, preBoleto.Ordem.NumeroOrdem.Value);
			this.DataBase.AddInParameter(dbCommand, "NR_SUBSEQ", DbType.Int32, preBoleto.Ordem.NumeroOrdemSubSequencia.Value);
			this.DataBase.AddInParameter(dbCommand, "DT_HORORD", DbType.DateTime, preBoleto.Ordem.HoraOrdem.Value);
			this.DataBase.AddInParameter(dbCommand, "DT_DATMOV", DbType.Date, preBoleto.DataPregao);
            //this.DataBase.AddInParameter(dbCommand, "TP_ORDEM", DbType.AnsiString, preBoleto.TipoOrdem); //excluido - eduardo - 20080131
            this.DataBase.AddInParameter(dbCommand, "TP_ORDEM", DbType.AnsiString, DBNull.Value); //incluido - eduardo - 20080131 - nao usado conforme email Arnaldo Salomao em 31/01/2008
            this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, Sinacor.Infra.Service.Common.EnumConverter.ToString<BusinessEntity.Enum.TipoMercado?>(preBoleto.Ordem.TipoMercado));

            

              //  BusinessEntity.Enum.
                
                //Sinacor.Servico.Bovespa.BovespaBase.Service.Util.TipoMercado.EnumToString(preBoleto.Ordem.TipoMercado)); //incluido - eduardo - 20080131

            //comentado - eduardo - 20080131 - substituido pela funcao [Comum.Util.TipoMercado.EnumToString]
            //switch (preBoleto.TipoMercado)
            //{
            //    case BusinessEntity.Enum.TipoMercado.Vista:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, "VIS");
            //        break;
            //    case BusinessEntity.Enum.TipoMercado.OpcaoCompra:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, "OPC");
            //        break;
            //    case BusinessEntity.Enum.TipoMercado.OpcaoVenda:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, "OPV");
            //        break;
            //    case BusinessEntity.Enum.TipoMercado.ExercicioOpcaoCompra:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, "EOC");
            //        break;
            //    case BusinessEntity.Enum.TipoMercado.ExercicioOpcaoVenda:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, "EOV");
            //        break;
            //    default:
            //        this.DataBase.AddInParameter(dbCommand, "CD_MERCAD", DbType.AnsiString, DBNull.Value);
            //        break;
            //}			
			
			this.DataBase.AddInParameter(dbCommand, "QT_ORDEM",  DbType.Int32, preBoleto.QuantidadeNegocio);
			this.DataBase.AddInParameter(dbCommand, "VL_PREPAP", DbType.Decimal, preBoleto.Preco);
			this.DataBase.AddInParameter(dbCommand, "CD_CONTRAPARTE",DbType.Int32, preBoleto.ContraParte);

            if (preBoleto.TipoCasamento != null)
                this.DataBase.AddInParameter(dbCommand, "IN_TOTAL", DbType.AnsiString, Sinacor.Infra.Service.Common.EnumConverter.ToString<BusinessEntity.Enum.TipoCasamento>(preBoleto.TipoCasamento));// DBNull.Value);//20080416 12:08- RValadao - O parametro IN_Total passa a receber parametro para atender a alteração do pré boleto..
            else
                this.DataBase.AddInParameter(dbCommand, "IN_TOTAL", DbType.AnsiString, DBNull.Value);

            

            ///resolver o tipo de estrategia
			switch (preBoleto.TipoEstrategia)
			{
				case BusinessEntity.Enum.TipoEstrategia.BOX:
					this.DataBase.AddInParameter(dbCommand, "TP_ESTRATEGIA",DbType.AnsiString, "B");
					break;
                case BusinessEntity.Enum.TipoEstrategia.DBX:
					this.DataBase.AddInParameter(dbCommand, "TP_ESTRATEGIA", DbType.AnsiString, "D");
					break;
                case BusinessEntity.Enum.TipoEstrategia.POP:
					this.DataBase.AddInParameter(dbCommand, "TP_ESTRATEGIA", DbType.AnsiString, "P");
					break;
                case BusinessEntity.Enum.TipoEstrategia.Nenhuma:
					this.DataBase.AddInParameter(dbCommand, "TP_ESTRATEGIA", DbType.AnsiString, "N");
					break;
			}

			this.DataBase.AddInParameter(dbCommand, "VL_DOLAR", DbType.Decimal,preBoleto.Cambio);
			this.DataBase.AddInParameter(dbCommand, "NR_OFEMEGA",DbType.Int32, 0);

			this.DataBase.ExecuteNonQuery(dbCommand);				

			return;
		}

		public void Excluir(BusinessEntity.PreBoleto preBoleto)
		{
			StringBuilder sql = new StringBuilder();

			sql.AppendLine("DELETE FROM TORDETD WHERE");
			sql.AppendLine("NR_SEQDET = :codigoPreBoleto");
			sql.AppendLine("AND DT_DATORD = :dataOrdem");
			sql.AppendLine("AND NR_SEQORD = :codigoOrdem");
			sql.AppendLine("AND NR_SUBSEQ = :codigoOrdemSequencia");
			DbCommand dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());

			this.DataBase.AddInParameter(dbCommand, "codigoPreBoleto", DbType.Int32, preBoleto.Numero);
			this.DataBase.AddInParameter(dbCommand, "dataOrdem", DbType.DateTime, preBoleto.Ordem.DataOrdem);
			this.DataBase.AddInParameter(dbCommand, "codigoOrdem", DbType.Int32, preBoleto.Ordem.NumeroOrdem);
			this.DataBase.AddInParameter(dbCommand, "codigoOrdemSequencia", DbType.Int32, preBoleto.Ordem.NumeroOrdemSubSequencia);

			this.DataBase.ExecuteNonQuery(dbCommand);

			return;
		}

		/// <summary>
		/// Metodo responsavel por realizar a consulta dos pre-boletos de forma analitica
		/// Data: 01/12/2007
		/// Autor: Diogo Milanez
		/// Obs: Criacao do metodo
        /// 
        /// Data: 28/01/2008
        /// Autor: Eduardo Sertorio
        /// Obs: Inclusao do fator de cotacao (FATOR_DE_COTACAO) do titulo no calculo do volume.
        /// Obs: Inclusao do numero da ordem usada com chave na ordem membro do preboleto de resposta.
        /// </summary>
		/// <param name="ordem"></param>
		/// <returns></returns>
        public List<BusinessEntity.PreBoleto> ConsultarAnalitico(BusinessEntity.Ordem ordem, System.Int32 tbotitfatFatorCotacao)
		{
			DbCommand dbCommand;
			StringBuilder sql = new StringBuilder();

			sql.AppendLine("SELECT TORDETD.QT_ORDEM,");//Quantidade;
			sql.AppendLine("TORDETD.VL_PREPAP,");//Precao
			sql.AppendLine("TORDETD.CD_CONTRAPARTE,");//Contraparte
			sql.AppendLine("TORDETD.IN_TOTAL,");//Tipo Casamento
            sql.AppendLine("TRUNC( TORDETD.QT_ORDEM *  TORDETD.VL_PREPAP / :FATOR_DE_COTACAO , 2 ),"); // Volume //alterado - eduardo - 20080128
			sql.AppendLine("NVL(SUM(TOREXEC.QT_NEGOCIO),0),"); // Quantidade Casada
			sql.AppendLine("TORDETD.NR_SEQDET,"); // Numero preboleto
			sql.AppendLine("TORDETD.TP_ESTRATEGIA,"); // Tipo Estrategia
			sql.AppendLine("NVL(TORDETD.VL_DOLAR,TORMOVD.VL_DOLAR)"); // Cambio
			sql.AppendLine("FROM TORDETD TORDETD, TOREXEC TOREXEC, TORMOVD TORMOVD");
			sql.AppendLine("WHERE TORDETD.DT_DATORD  = :dataOrdem");
			sql.AppendLine("AND TORDETD.NR_SEQORD  = :numeroOrdem");
			sql.AppendLine("AND TORDETD.NR_SUBSEQ  = :numeroOrdemSequencia");
			sql.AppendLine("AND TORDETD.DT_DATMOV  = :dataPregao");
			sql.AppendLine("AND TORDETD.NR_SEQDET <> 0");
			sql.AppendLine("AND TORDETD.NR_SEQDET  =  TOREXEC.NR_SEQDET(+)");
			sql.AppendLine("AND TORDETD.NR_SEQORD  =  TOREXEC.NR_SEQORD(+)");
			sql.AppendLine("AND TORDETD.DT_DATMOV  =  TOREXEC.DT_NEGOCIO(+)");
			sql.AppendLine("AND TOREXEC.NR_SEQDET(+) <> 0");
			sql.AppendLine("AND TORMOVD.DT_DATORD  = TORDETD.DT_DATORD");
			sql.AppendLine("AND TORMOVD.NR_SEQORD  = TORDETD.NR_SEQORD");
			sql.AppendLine("AND TORMOVD.NR_SUBSEQ  = TORDETD.NR_SUBSEQ");
			sql.AppendLine("GROUP BY TORDETD.NR_SEQDET,");
			sql.AppendLine("TORDETD.QT_ORDEM,");
			sql.AppendLine("TORDETD.VL_PREPAP,");
			sql.AppendLine("TORDETD.CD_CONTRAPARTE,");
			sql.AppendLine("TORDETD.IN_TOTAL,");
            sql.AppendLine("TRUNC( TORDETD.QT_ORDEM *  TORDETD.VL_PREPAP / :FATOR_DE_COTACAO , 2 ),"); // Volume //alterado - eduardo - 20080128
            sql.AppendLine("TORDETD.TP_ESTRATEGIA, NVL(TORDETD.VL_DOLAR,TORMOVD.VL_DOLAR)");

			dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());
            this.DataBase.AddInParameter(dbCommand, "FATOR_DE_COTACAO", DbType.Int32, tbotitfatFatorCotacao); //incluido - eduardo - 20080128
            this.DataBase.AddInParameter(dbCommand, "dataOrdem", DbType.Date, ordem.DataOrdem);
			this.DataBase.AddInParameter(dbCommand, "numeroOrdem", DbType.Int32, ordem.NumeroOrdem);
			this.DataBase.AddInParameter(dbCommand, "numeroOrdemSequencia", DbType.Int32, ordem.NumeroOrdemSubSequencia);
			this.DataBase.AddInParameter(dbCommand, "dataPregao", DbType.Date, ordem.DataPregao);

			IDataReader reader = this.DataBase.ExecuteReader(dbCommand);
			BusinessEntity.PreBoleto preBoleto;
			List<BusinessEntity.PreBoleto> listaPreBoleto = new List<BusinessEntity.PreBoleto>(); ;
			while (reader.Read())
			{
				preBoleto = new BusinessEntity.PreBoleto();
				preBoleto.Ordem = new BusinessEntity.Ordem();
				preBoleto.QuantidadeNegocio = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetDecimal(0));
				preBoleto.Preco = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetDecimal(1));
                //20080423 10:41 - RValadao
                //Verifica se o cd_contraparte é nulo. Correção bug 3481
                if (!reader.IsDBNull(2))
                {
                    preBoleto.ContraParte = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorInt32(reader.GetInt32(2));
                }
                
                //20080424 14:17 - RValadao
                //Tipo de casamento que retorna do campo IN_TOTAL referente ao tipo de casamento do pré boleto.
                if (!reader.IsDBNull(3))
                {
                    switch (reader.GetString(3))
                    {
                        case "P":
                            preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Parcial;
                            break;
                        case "T":
                            preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Total;
                            break;
                        case "N":
                            preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Nada;
                            break;
                        default:
                            preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Nada;
                            break;
                    }
                }
                else
                {
                    preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Nada; 
                }

				preBoleto.Volume = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetDecimal(4));
                preBoleto.Ordem.NumeroOrdem = ordem.NumeroOrdem.Value; //incluido - eduardo - 20080129
                preBoleto.Ordem.DataOrdem = ordem.DataOrdem.Value; //incluido - eduardo - 20080129
                preBoleto.Ordem.NumeroOrdemSubSequencia = ordem.NumeroOrdemSubSequencia.Value; //incluido - eduardo - 20080129
                preBoleto.DataPregao = ordem.DataPregao.Value; //incluido - eduardo - 20080129
                preBoleto.Ordem.QuantidadeCasada = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetDecimal(5));
                preBoleto.Numero = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorInt32(reader.GetInt32(6));
                //20070417 - 15:20 - RValadao.7Comm
                //Incluido o campo IndicadorDesprezaSaldo para mostrar na tela de pre boleto.
                preBoleto.Ordem.IndicadorDesprezaSaldo = ordem.IndicadorDesprezaSaldo;

                switch (reader.GetString(7))
                {
                    case "N":
                        preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.Nenhuma;
                        break;
                    case "P":
                        preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.POP;
                        break;
                    case "B":
                        preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.BOX;
                        break;
                    case "D":
                        preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.DBX;
                        break;
                    ///se nulo ou algum outro valor, assumir o valor default
                    default:
                        preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.Nenhuma;
                        break;
                }

				preBoleto.Cambio = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetDecimal(8));

                //20080424 14:18 - RValadao
                //Tipo de casamento calculado através da quantidade casada e quantidade do negócio
                //referente ao batimento entre negócio e pré boleto.
                if (!preBoleto.Ordem.QuantidadeCasada.HasValue || preBoleto.Ordem.QuantidadeCasada == 0)
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.NaoCasadas;
                }
                else if (preBoleto.Ordem.QuantidadeCasada < preBoleto.QuantidadeNegocio)
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.CasadasParte;
                }
                else
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.Casadas;
                }


				listaPreBoleto.Add(preBoleto);
			}
            
            reader.Close();
			return listaPreBoleto;

		}



		/// <summary>
		/// MEtodo responsavel por realizar a consulta dos preboletos 
		/// Data: 01/12/2007
		/// Autor: Diogo Milanez
		/// Obs: Criacao do Metodo
        /// 
        /// Data: 28/01/2008
        /// Autor: Eduardo Sertorio
        /// Obs: Inclusao do fator de cotacao (FATOR_DE_COTACAO) do titulo no calculo do volume.
        /// Obs: Inclusao do numero da ordem usada com chave na ordem membro do preboleto de resposta.
        /// </summary>
		/// <param name="preBoleto"></param>
		/// <returns></returns>
        public List<BusinessEntity.PreBoleto> ConsultarSintetico(BusinessEntity.Ordem ordem, System.Int32 tbotitfatFatorCotacao)
		{
			DbCommand dbCommand;			
			StringBuilder sql = new StringBuilder();

			sql.AppendLine("SELECT SUM(TORDETD.QT_ORDEM),");//Quantidade"
			sql.AppendLine("TORDETD.VL_PREPAP,");//Preco
			sql.AppendLine("0,"); //Contraparte
			sql.AppendLine("NULL,"); //TipoCasamento
            sql.AppendLine("SUM( TRUNC( TORDETD.QT_ORDEM *  TORDETD.VL_PREPAP / :FATOR_DE_COTACAO , 2 ) ),"); //Volume //alterado - eduardo - 20080128
			sql.AppendLine("NVL(TOREXEC.QT_NEGOCIO,0),");//QuantidadeCasada
			sql.AppendLine("0,"); //NumeroPreBoleto
			sql.AppendLine("NULL,");//Estrategia
			sql.AppendLine("NVL(TORDETD.VL_DOLAR,TORMOVD.VL_DOLAR)");//Cambio
			sql.AppendLine("FROM TORDETD TORDETD, V_TOREXEC06 TOREXEC, TORMOVD TORMOVD");
			sql.AppendLine("WHERE TORDETD.DT_DATORD  = :dataOrdem");
			sql.AppendLine("AND TORDETD.NR_SEQORD  = :numeroOrdem");
			sql.AppendLine("AND TORDETD.NR_SUBSEQ  = :numeroOrdemSequencia");
			sql.AppendLine("AND TORDETD.DT_DATMOV  = :dataPregao");
			sql.AppendLine("AND TORDETD.NR_SEQDET <> 0");
			sql.AppendLine("AND TORDETD.NR_SEQORD  =  TOREXEC.NR_SEQORD(+)");
			sql.AppendLine("AND TORDETD.DT_DATMOV  =  TOREXEC.DT_DATMOV(+)");
            sql.AppendLine("AND TORDETD.NR_SUBSEQ  =  TOREXEC.NR_SUBSEQ(+)");            
			sql.AppendLine("AND TORDETD.VL_PREPAP  = TOREXEC.VL_NEGOCIO(+)");
			sql.AppendLine("AND TORMOVD.DT_DATORD  = TORDETD.DT_DATORD");
			sql.AppendLine("AND TORMOVD.NR_SEQORD  = TORDETD.NR_SEQORD");
			sql.AppendLine("AND TORMOVD.NR_SUBSEQ  = TORDETD.NR_SUBSEQ");
			sql.AppendLine("GROUP BY TORDETD.VL_PREPAP,TOREXEC.QT_NEGOCIO,NVL(TORDETD.VL_DOLAR,TORMOVD.VL_DOLAR)");

			dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());
            this.DataBase.AddInParameter(dbCommand, "FATOR_DE_COTACAO", DbType.Int32, tbotitfatFatorCotacao); //incluido - eduardo - 20080128
            this.DataBase.AddInParameter(dbCommand, "dataOrdem", DbType.Date, ordem.DataOrdem);
			this.DataBase.AddInParameter(dbCommand, "numeroOrdem", DbType.Int32, ordem.NumeroOrdem);
			this.DataBase.AddInParameter(dbCommand, "numeroOrdemSequencia", DbType.Int32, ordem.NumeroOrdemSubSequencia);
			this.DataBase.AddInParameter(dbCommand, "dataPregao", DbType.Date, ordem.DataPregao);

			IDataReader reader = this.DataBase.ExecuteReader(dbCommand);
			BusinessEntity.PreBoleto preBoleto;
			List<BusinessEntity.PreBoleto> listaPreBoleto = new List<BusinessEntity.PreBoleto>(); ;
			while (reader.Read())
			{
				preBoleto = new BusinessEntity.PreBoleto();
				preBoleto.Ordem = new BusinessEntity.Ordem();

                /// Data:30/01/2008 12:08
                /// Autor:Dmilanez.7comm
                /// Obs: ATENCAO AO FAZER MERGE
                /// Codigo teve de ser r eadicionado
                preBoleto.Ordem.NumeroOrdem = ordem.NumeroOrdem;
                preBoleto.Ordem.DataOrdem = ordem.DataOrdem;
                preBoleto.Ordem.NumeroOrdemSubSequencia = ordem.NumeroOrdemSubSequencia;
                //20070413 - 11:37 - RValadao.7Comm
                //Incluido o campo IndicadorDesprezaSaldo para mostrar na tela de pre boleto.
                preBoleto.Ordem.IndicadorDesprezaSaldo = ordem.IndicadorDesprezaSaldo;
				preBoleto.QuantidadeNegocio = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetValue(0));
				preBoleto.Preco = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetValue(1));
				preBoleto.ContraParte = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorInt32(reader.GetValue(2));
                preBoleto.TipoCasamento = BusinessEntity.Enum.TipoCasamento.Nada; ///query sempre retorna null reader.GetString(3);
                preBoleto.Volume = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetValue(4));
                preBoleto.DataPregao = ordem.DataPregao.Value; //incluido - eduardo - 20080129
				preBoleto.Ordem.QuantidadeCasada = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetValue(5));
				preBoleto.Numero = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorInt32(reader.GetValue(6));
                preBoleto.TipoEstrategia = BusinessEntity.Enum.TipoEstrategia.Nenhuma;///query sempre retorna null reader.GetString(7);
				preBoleto.Cambio = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDecimal(reader.GetValue(8));


                //20080424 14:18 - RValadao
                //Tipo de casamento calculado através da quantidade casada e quantidade do negócio
                //referente ao batimento entre negócio e pré boleto.
                if (!preBoleto.Ordem.QuantidadeCasada.HasValue || preBoleto.Ordem.QuantidadeCasada == 0)
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.NaoCasadas;
                }
                else if (preBoleto.Ordem.QuantidadeCasada < preBoleto.QuantidadeNegocio)
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.CasadasParte;
                }
                else
                {
                    preBoleto.TipoSituacaoCasamento = BusinessEntity.Enum.TipoSituacaoCasamento.Casadas;
                }

				listaPreBoleto.Add(preBoleto);
			}
            
            reader.Close();
			return listaPreBoleto;
		}

		/// <summary>
		/// metodo responsavel por realizar o casamento dos pre-boletos associados
		/// a uma ordem
		/// Data: 30/11/2007
		/// Autor: Diogo Milanez
		/// Obs: criacao do metodo
		/// </summary>
		/// <param name="ordem"></param>
		/// <returns></returns>	 
		public BusinessEntity.RetornoCasamento RealizarCasamento(BusinessEntity.Ordem ordem,BusinessEntity.Enum.TipoCasamentoPreBoleto tipoCasamento)
		{
			DbCommand dbCommand;
			
            try
            {
                string dataOrdemFormatada = Funcoes.FormatarData(ordem.DataOrdem.Value, "-");
                string dataPregaoFormatada = Funcoes.FormatarData(ordem.DataPregao.Value, "-");

                if (tipoCasamento == BusinessEntity.Enum.TipoCasamentoPreBoleto.FIN)
                    dbCommand = this.DataBase.GetStoredProcCommand("PR_CASDET.CASAMENTO_FIN");
                else
                    dbCommand = this.DataBase.GetStoredProcCommand("PR_CASDET.CASAMENTO_ESP");

                this.DataBase.AddInParameter(dbCommand, "P_DATORD", DbType.String, dataOrdemFormatada);
                this.DataBase.AddInParameter(dbCommand, "P_NUMORD", DbType.Int32, ordem.NumeroOrdem);
                this.DataBase.AddInParameter(dbCommand, "P_SUBSEQ", DbType.Int32, ordem.NumeroOrdemSubSequencia);
                this.DataBase.AddInParameter(dbCommand, "P_DATMOV", DbType.String, dataPregaoFormatada);
                this.DataBase.AddOutParameter(dbCommand, "P_OCORRE", DbType.AnsiString, 2000);
                this.DataBase.AddOutParameter(dbCommand, "P_VAL", DbType.AnsiString, 2000);

                ///ATENCAO
                ///Esta execucao vai falhar uma vez que a procedure esta realizando
                ///commit internamente
                ///A procedure devera ser alterada para corrigir erro
                this.DataBase.ExecuteNonQuery(dbCommand);

                BusinessEntity.RetornoCasamento retorno = new BusinessEntity.RetornoCasamento();
                String pOcorre = Convert.ToString(this.DataBase.GetParameterValue(dbCommand, "P_OCORRE"));
                String pVal = Convert.ToString(this.DataBase.GetParameterValue(dbCommand, "P_VAL"));

                switch (pOcorre)
                {
                    case "T":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.CasamentoTotal;
                        retorno.MensagemCasamento.Descricao = "Casou todos os pré-boletos.";
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    case "P":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.CasamentoParcial;
                        retorno.MensagemCasamento.Descricao = "Casou parte dos pré-boletos.";
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    case "N":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.NadaFoiCasado;
                        retorno.MensagemCasamento.Descricao = "Não casou nenhum pré-boleto.";
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    case "C":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.OrdemJaCasadaOuInconsistenciaOfertaRecebida;
                        retorno.MensagemCasamento.Descricao = "Ordem já casada ou inconsistência de Oferta recebida.";
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    case "LP":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.OrdemJaCasadaOuInconsistenciaOfertaRecebida;
                        retorno.MensagemCasamento.Descricao = "Existe prioridade " + pVal;
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    case "LC":
                        retorno.TipoRetornoCasamento = BusinessEntity.Enum.TipoRetornoCasamento.OrdemJaCasadaOuInconsistenciaOfertaRecebida;
                        retorno.MensagemCasamento.Descricao = "Existe concorrência " + pVal;
                        retorno.MensagemCasamento.Codigo = 0;///posteriormente sera alterado para poder suportar multidiomas
                        break;
                    default:
                        return null;
                }

                return retorno;
            }
            catch (System.Data.OracleClient.OracleException oraException)
            {
                //20080504 19:09 - RValadao
                //Dispara tratamento de exceção no retorno da proc quando disparado raiseerror
                switch (oraException.Code)
                {
                    case 20233:
                        throw new BusinessException(ERRO_EXISTE_PRIORIDADE_MAIOR);//Existe prioridade maior!
                    case 20232:
                        throw new BusinessException(ERRO_EXISTE_CONCORRENCIA);//Existe concorrência.
                }
            }

            return null;
		}

		public void RealizarDescasamento(BusinessEntity.PreBoleto preBoleto)
		{
			DbCommand dbCommand;

			dbCommand = this.DataBase.GetStoredProcCommand("PR_CASMAN.CASMAN");
			this.DataBase.AddInParameter(dbCommand, "P_SEQDET", DbType.Int32, preBoleto.Numero);

			///ATENCAO
			///Esta execucao vai falhar uma vez que a procedure esta realizando
			///commit internamente
			///A procedure devera ser alterada para corrigir erro
			this.DataBase.ExecuteNonQuery(dbCommand);

		}

        /// <summary>
        /// Data : 30/01/2008
        /// Autor: Eduardo Sertorio
        /// Obs. : Criacao do metodo para obter data do pregao a partir do preboleto
        /// </summary>
        /// <param name="preBoleto"></param>
        /// <returns></returns>
        public DateTime? ConsultarDataPregaoPreBoleto(BusinessEntity.PreBoleto preBoleto)
        {
            DateTime? dataPregao = null;

            StringBuilder sql = new StringBuilder();

            sql.AppendLine("SELECT DT_DATMOV FROM TORDETD ");
            sql.AppendLine("WHERE NR_SEQDET = :codigoPreBoleto");
            sql.AppendLine("AND DT_DATORD = :dataOrdem");
            sql.AppendLine("AND NR_SEQORD = :codigoOrdem");
            sql.AppendLine("AND NR_SUBSEQ = :codigoOrdemSequencia");

            DbCommand dbCommand = this.DataBase.GetSqlStringCommand(sql.ToString());

            this.DataBase.AddInParameter(dbCommand, "codigoPreBoleto", DbType.Int32, preBoleto.Numero);
            this.DataBase.AddInParameter(dbCommand, "dataOrdem", DbType.DateTime, preBoleto.Ordem.DataOrdem.Value);
            this.DataBase.AddInParameter(dbCommand, "codigoOrdem", DbType.Int32, preBoleto.Ordem.NumeroOrdem.Value);
            this.DataBase.AddInParameter(dbCommand, "codigoOrdemSequencia", DbType.Int32, preBoleto.Ordem.NumeroOrdemSubSequencia.Value);

            IDataReader reader = this.DataBase.ExecuteReader(dbCommand);

            if (reader.Read())
                dataPregao = Sinacor.Servicos.Comum.Util.SGBD.Funcoes.BDValorDateTime(reader.GetValue(0),true);

            reader.Close(); //incluido - esertorio - 200804291058 - ref issue ID0003836

            return dataPregao;
        }



        ///<sumary>
        /// Converte Tipo de Mercado de String para Enum
        /// Data: 11/12/2007
        /// Autor: Eduarddo Sertorio
        /// Observacoes: Criacao do enum
        /// 
        /// Data:28/01/2008 16:50
        /// Autor:Dmilanez.7comm
        /// Obs:
        /// Alterado de forma a conter o mercado BOX
        ///<sumary>
        public static BusinessEntity.Enum.TipoMercado? StringToEnum(string value)
        {
            BusinessEntity.Enum.TipoMercado? retorno;
            switch (value)
            {
                case "VIS":
                    retorno = BusinessEntity.Enum.TipoMercado.Vista;
                    break;
                case "OPC":
                    retorno = BusinessEntity.Enum.TipoMercado.OpcaoCompra;
                    break;
                case "OPV":
                    retorno = BusinessEntity.Enum.TipoMercado.OpcaoVenda;
                    break;
                case "EOC":
                    retorno = BusinessEntity.Enum.TipoMercado.ExercicioOpcaoCompra;
                    break;
                case "EOV":
                    retorno = BusinessEntity.Enum.TipoMercado.ExercicioOpcaoVenda;
                    break;
                case "FRA":
                    retorno = BusinessEntity.Enum.TipoMercado.Fracionario;
                    break;
                case "EST":
                    retorno = BusinessEntity.Enum.TipoMercado.Estruturado;
                    break;
                case "LEI":
                    retorno = BusinessEntity.Enum.TipoMercado.Leilao;
                    break;
                case "TER":
                    retorno = BusinessEntity.Enum.TipoMercado.Termo;
                    break;
                case "LNC":
                    retorno = BusinessEntity.Enum.TipoMercado.LeilaoNaoCotados;
                    break;
                case "FUT":
                    retorno = BusinessEntity.Enum.TipoMercado.Futuro;
                    break;
                case "VFU":
                    retorno = BusinessEntity.Enum.TipoMercado.VencimentoFuturo;
                    break;
                case "BOX":
                    retorno = BusinessEntity.Enum.TipoMercado.BOX;
                    break;
                case "IER":
                    retorno = BusinessEntity.Enum.TipoMercado.IntegralizacaoResgateCotas;
                    break;
                case "CET":
                    retorno = BusinessEntity.Enum.TipoMercado.CotasETF;
                    break;
                default:
                    retorno = null;
                    break;
            }
            return retorno;
        }

        ///<sumary>
        /// Converte Tipo de Mercado de Enum para String
        /// Data: 11/12/2007
        /// Autor: Eduarddo Sertorio
        /// Observacoes: Criacao do enum
        /// 
        /// Data:28/01/2008 16:50
        /// Autor:Dmilanez.7comm
        /// Obs:
        /// Alterado de forma a conter o mercado BOX
        ///<sumary>
        public static string EnumToString(BusinessEntity.Enum.TipoMercado value)
        {
            string retorno;
            switch (value)
            {
                case BusinessEntity.Enum.TipoMercado.Vista:
                    retorno = "VIS";
                    break;
                case BusinessEntity.Enum.TipoMercado.OpcaoCompra:
                    retorno = "OPC";
                    break;
                case BusinessEntity.Enum.TipoMercado.OpcaoVenda:
                    retorno = "OPV";
                    break;
                case BusinessEntity.Enum.TipoMercado.ExercicioOpcaoCompra:
                    retorno = "EOC";
                    break;
                case BusinessEntity.Enum.TipoMercado.ExercicioOpcaoVenda:
                    retorno = "EOV";
                    break;
                case BusinessEntity.Enum.TipoMercado.Fracionario:
                    retorno = "FRA";
                    break;
                case BusinessEntity.Enum.TipoMercado.Estruturado:
                    retorno = "EST";
                    break;
                case BusinessEntity.Enum.TipoMercado.Leilao:
                    retorno = "LEI";
                    break;
                case BusinessEntity.Enum.TipoMercado.Termo:
                    retorno = "TER";
                    break;
                case BusinessEntity.Enum.TipoMercado.LeilaoNaoCotados:
                    retorno = "LNC";
                    break;
                case BusinessEntity.Enum.TipoMercado.Futuro:
                    retorno = "FUT";
                    break;
                case BusinessEntity.Enum.TipoMercado.VencimentoFuturo:
                    retorno = "VFU";
                    break;
                case BusinessEntity.Enum.TipoMercado.BOX:
                    retorno = "BOX";
                    break;
                case BusinessEntity.Enum.TipoMercado.IntegralizacaoResgateCotas:
                    retorno = "IER";
                    break;
                case BusinessEntity.Enum.TipoMercado.CotasETF:
                    retorno = "CET";
                    break;
                default: //BusinessEntity.Enum.TipoMercado.Indefinido
                    retorno = "";
                    break;
            }
            return retorno;
        }

        public static string EnumToString(BusinessEntity.Enum.TipoMercado? value)
        {
            if (value.HasValue)
                return EnumToString(value.Value);
            else
                return null;
        }

	}
}
